package com.geoai.uimap.core.mapbox

import com.mapbox.mapboxsdk.geometry.LatLng
import com.mapbox.mapboxsdk.plugins.annotation.Line
import com.mapbox.mapboxsdk.plugins.annotation.LineOptions
import com.mapbox.mapboxsdk.utils.ColorUtils
import com.geoai.uimap.api.IGEOMap
import com.geoai.uimap.api.GEOMapArc
import com.geoai.uimap.geo.Point
import com.geoai.uimap.geo.SimpleProjection
import com.geoai.uimap.utils.MathUtils
import com.geoai.uimap.utils.getMapBoxGeometry

class MapboxArc(private val map: IGEOMap) : GEOMapArc() {
    private var mArcLine: Line? = null

    override fun show(): GEOMapArc {
        if (mArcInfo == null) return this
        val mapBoxGeometry = map.getMapBoxGeometry() ?: return this
//        draw(mapBoxGeometry)

        val simpleProjection = SimpleProjection(mArcInfo!!.start) //基点
        val s = simpleProjection.GeoPoint2Point(mArcInfo!!.start)
        val e = simpleProjection.GeoPoint2Point(mArcInfo!!.end)
        val mArcAngle = mArcInfo!!.mAngel
        val mClockwise = mArcInfo!!.mClockwise
        val points = mutableListOf<LatLng>()

        var subAngle = 0.0
        while (Math.abs(subAngle) <= mArcAngle) {
            val newAngle = mArcInfo!!.startAngle.toDouble() + subAngle
            val mid = MathUtils.getPointOnCircle(mArcInfo!!.circle, Math.toRadians(newAngle))
            val midPoint = simpleProjection.Point2GeoPoint(Point(mid.x, mid.y))
            points.add(LatLng(midPoint.latitude, midPoint.longitude))
            if (mClockwise) {
                subAngle -= 1.0
            } else {
                subAngle += 1.0
            }
        }
        mapBoxGeometry.getLineManager()?.let {
            val lineOptions = LineOptions()
                    .withLatLngs(points)
                    .withLineColor(ColorUtils.colorToRgbaString(mLineColor))
                    .withLineWidth(mWidth)
            mArcLine = it.create(lineOptions)
        }
        return this
    }

    private fun draw(mapBoxGeometry:MapboxGeometryManager){
        val simpleProjection = SimpleProjection(mArcInfo!!.start) //基点
        val s = simpleProjection.GeoPoint2Point(mArcInfo!!.start)
        val e = simpleProjection.GeoPoint2Point(mArcInfo!!.end)
        val center = Point((s.x + e.x) / 2, (s.y + e.y) / 2)

        var subAngle = 0.0
        val points = mutableListOf<LatLng>()
        while (Math.abs(subAngle) <= mArcInfo!!.mAngel) {
            val mid = Point()
            val angleCos = Math.cos(Math.toRadians(subAngle))
            val angleSin = Math.sin(Math.toRadians(subAngle))
            mid.x = (center.x + (s.x - center.x) * angleCos - (s.y - center.y) * angleSin)
            mid.y = (center.y + (s.x - center.x) * angleSin + (s.y - center.y) * angleCos)
            val newMid = simpleProjection.Point2GeoPoint(mid)
            points.add(LatLng(newMid.latitude, newMid.longitude))
            if (mArcInfo!!.mClockwise) {
                subAngle -= 1.0
            } else {
                subAngle += 1.0
            }
        }
        mapBoxGeometry.getLineManager()?.let {
            val lineOptions = LineOptions()
                .withLatLngs(points)
                .withLineColor(ColorUtils.colorToRgbaString(mLineColor))
                .withLineWidth(mWidth)
            mArcLine = it.create(lineOptions)
        }
    }


    override fun destroy() {
        mArcLine?.let {
            map.getMapBoxGeometry()?.getLineManager()?.delete(it)
        }
    }
}